package com.tianjishuju.cimiss.station.station.util;

import java.io.File;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.LinkedList;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.io.SocketInputStream;
import org.apache.log4j.Logger;



public class FtpUtils {
	// ftp服务器地址
	public static String hostname = "hadoop";
	// ftp服务器端口号默认为21
	public static Integer port = 21;
	// ftp登录账号
	public static String username = "eric";
	// ftp登录密码
	public static String password = "qaz789";

	public static FTPClient ftpClient = null;
	private static Logger logger = Logger.getLogger(FtpUtils.class);
	// ftp 存储目录全路径 多个目录
	private static ArrayList<String> ftpdirctorys = new ArrayList<String>();

	/**
	 * 初始化ftp服务器
	 */
	public static void initFtpClient(String hostname1, Integer port1, String username1, String password1) {
		hostname = hostname1;
		port = port1;
		username = username1;
		password = password1;
		
		ftpClient = new FTPClient();
		ftpClient.setControlEncoding("utf-8");
		try {
			System.out.println("connecting...ftp服务器:" + hostname + ":" + port);
			ftpClient.connect(hostname, port); // 连接ftp服务器
			ftpClient.login(username, password); // 登录ftp服务器
			int replyCode = ftpClient.getReplyCode(); // 是否成功登录服务器
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				System.out.println("connect failed...ftp服务器:" + hostname + ":" + port);
			}
			System.out.println("connect successfu...ftp服务器:" + hostname + ":" + port);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 初始化ftp服务器
	 */
	public static void initFtpClient() {
		ftpClient = new FTPClient();
		ftpClient.setControlEncoding("utf-8");
		try {
			System.out.println("connecting...ftp服务器:" + hostname + ":" + port);
			ftpClient.connect(hostname, port); // 连接ftp服务器
			ftpClient.login(username, password); // 登录ftp服务器
			int replyCode = ftpClient.getReplyCode(); // 是否成功登录服务器
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				System.out.println("connect failed...ftp服务器:" + hostname + ":" + port);
			}
			System.out.println("connect successfu...ftp服务器:" + hostname + ":" + port);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 上传文件
	 * 
	 * @param pathname
	 *            ftp服务保存地址
	 * @param fileName
	 *            上传到ftp的文件名
	 * @param originfilename
	 *            待上传文件的名称（绝对地址） *
	 * @return
	 */
	public static boolean uploadFile(String pathname, String fileName, String originfilename) {
		boolean flag = false;
		InputStream inputStream = null;
		try {
			System.out.println("开始上传文件");
			System.out.println(originfilename);
			File f = new File(originfilename);
			FileInputStream fis =new FileInputStream(f);
			inputStream = fis;
			FtpUtils.initFtpClient("10.0.1.177", 21, "tianji", "000000");
//			FtpUtils.initFtpClient("10.0.4.159", 21, "eric", "qaz789");
			
			ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
			CreateDirecroty(pathname);
			ftpClient.makeDirectory(pathname);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			flag = true;
			System.out.println("上传文件成功");
		} catch (Exception e) {
			System.out.println("上传文件失败");
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != inputStream) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}

	/**
	 * 上传文件
	 * 
	 * @param pathname
	 *            ftp服务保存地址
	 * @param fileName
	 *            上传到ftp的文件名
	 * @param inputStream
	 *            输入文件流
	 * @return
	 */
	public static boolean uploadFile(String pathname, String fileName, InputStream inputStream) {
		boolean flag = false;
		try {
			System.out.println("开始上传文件");
//			initFtpClient();
			ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
			CreateDirecroty(pathname);
			ftpClient.makeDirectory(pathname);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			flag = true;
			System.out.println("上传文件成功");
		} catch (Exception e) {
			System.out.println("上传文件失败");
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != inputStream) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}

	// 改变目录路径
	public static boolean changeWorkingDirectory(String directory) {
		boolean flag = true;
		try {
			flag = ftpClient.changeWorkingDirectory(directory);
			if (flag) {
				System.out.println("进入文件夹" + directory + " 成功！");

			} else {
				System.out.println("进入文件夹" + directory + " 失败！开始创建文件夹");
			}
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return flag;
	}

	// 创建多层目录文件，如果有ftp服务器已存在该文件，则不创建，如果无，则创建
	public static boolean CreateDirecroty(String remote) throws IOException {
		boolean success = true;
		String directory = remote + "/";
		// 如果远程目录不存在，则递归创建远程服务器目录
		if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			String path = "";
			String paths = "";
			while (true) {
				String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
				path = path + "/" + subDirectory;
				if (!existFile(path)) {
					if (makeDirectory(subDirectory)) {
						changeWorkingDirectory(subDirectory);
					} else {
						System.out.println("创建目录[" + subDirectory + "]失败");
						changeWorkingDirectory(subDirectory);
					}
				} else {
					changeWorkingDirectory(subDirectory);
				}

				paths = paths + "/" + subDirectory;
				start = end + 1;
				end = directory.indexOf("/", start);
				// 检查所有目录是否创建完毕
				if (end <= start) {
					break;
				}
			}
		}
		return success;
	}

	// 判断ftp服务器文件是否存在
	public static boolean existFile(String path) throws IOException {
		boolean flag = false;
		FTPFile[] ftpFileArr = ftpClient.listFiles(path);
		if (ftpFileArr.length > 0) {
			flag = true;
		}
		return flag;
	}

	// 创建目录
	public static boolean makeDirectory(String dir) {
		boolean flag = true;
		try {
			flag = ftpClient.makeDirectory(dir);
			if (flag) {
				System.out.println("创建文件夹" + dir + " 成功！");

			} else {
				System.out.println("创建文件夹" + dir + " 失败！");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * * 删除文件 *
	 * 
	 * @param pathname
	 *            FTP服务器保存目录 *
	 * @param filename
	 *            要删除的文件名称 *
	 * @return
	 */
	public static boolean deleteFile(String pathname, String filename) {
		boolean flag = false;
		try {
			System.out.println("开始删除文件");
			initFtpClient();
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.dele(filename);
			ftpClient.logout();
			flag = true;
			System.out.println("删除文件成功");
		} catch (Exception e) {
			System.out.println("删除文件失败");
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;
	}

	/**
	 * * 下载文件 *
	 * 
	 * @param pathname
	 *            FTP服务器文件目录 *
	 * @param filename
	 *            文件名称 *
	 * @param localpath
	 *            下载后的文件路径 *
	 * @return
	 */
	public static boolean downloadFile(String pathname, String filename, String localpath) {
		boolean flag = false;
		OutputStream os = null;
		try {
			System.out.println("开始下载文件");
			initFtpClient();
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname);
			FTPFile[] ftpFiles = ftpClient.listFiles();
			for (FTPFile file : ftpFiles) {
				String fn = file.getName();
				if (filename.equalsIgnoreCase(file.getName())) {
					File localFile = new File(localpath + "/" + file.getName());
					// if(!localFile.exists()){
					// System.out.println("111111");
					// localFile.createNewFile();
					// System.out.println("222222");
					// }
					os = new FileOutputStream(localFile);
					ftpClient.retrieveFile(file.getName(), os);
					os.close();
				}
			}
			ftpClient.logout();
			flag = true;
			System.out.println("下载文件成功");
		} catch (Exception e) {
			System.out.println("下载文件失败");
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != os) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;
	}

	/*
	 * ftp 遍历指定目录中的文件或者目录，不递归处理 单层
	 */
	public static ArrayList<String> GetFileFtp(String pathname) {
		try {
			System.out.println("开始遍历文件");
			initFtpClient();
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname);
			FTPFile[] ftpFiles = ftpClient.listFiles();
			for (FTPFile file : ftpFiles) {
				ftpdirctorys.add(pathname + "/" + file.getName());
			}
			System.out.println("遍历文件成功");
		} catch (Exception e) {
			System.out.println("遍历文件失败");
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return ftpdirctorys;
	}

	/*
	 * ftp 递归遍历所有目录中的文件 递归2层 pathname = /data/in /data/in/aa.txt
	 * /data/in/user.txt /data/in/22/1.txt /data/in/22/44.txt
	 * /data/in/33/9999.txt
	 */
	public static ArrayList<String> GetFileFtp2(String pathname) {
		int fileNum = 0;
		int folderNum = 0;
		try {
			System.out.println("开始遍历文件");
//			initFtpClient();
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname);
			LinkedList<FTPFile> list = new LinkedList<FTPFile>();
			FTPFile[] ftpFiles = ftpClient.listFiles();
			for (FTPFile file1 : ftpFiles) {
				if (file1.isDirectory()) {
					System.out.println("文件夹:" + pathname + "/" + file1.getName());
					list.add(file1);
					folderNum++;
				} else {
					System.out.println("文件:" + pathname + "/" + file1.getName());
					if (!file1.getName().startsWith(".")) {
						ftpdirctorys.add(pathname + "/" + file1.getName());
					}
					fileNum++;
				}
			}

			FTPFile temp_file;
			while (!list.isEmpty()) {
				temp_file = list.removeFirst();
				String fn = temp_file.getName();
				ftpClient.changeWorkingDirectory(pathname + "/" + temp_file.getName());
				ftpFiles = ftpClient.listFiles();
				for (FTPFile file2 : ftpFiles) {
					System.out.println("文件夹:" + pathname + "/" + temp_file.getName() + "/" + file2.getName());
					if (file2.isDirectory()) {
						list.add(file2);
						folderNum++;
					} else {
						String fn1 = pathname + "/" + temp_file.getName() + "/" + file2.getName();
						if (!file2.getName().startsWith(".")) {
							ftpdirctorys.add(pathname + "/" + temp_file.getName() + "/" + file2.getName());
						}
						fileNum++;
					}
				}
			}
			System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);
			System.out.println("遍历文件成功");
		} catch (Exception e) {
			System.out.println("遍历文件失败");
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return ftpdirctorys;
	}

	/**
	 * 关闭连接
	 * 
	 */

	public static void closeConnect() {
		try {
			ftpClient.logout();
			System.out.println("disconnect success");
		} catch (IOException ex) {
			System.out.println("not disconnect");
			ex.printStackTrace();
			throw new RuntimeException(ex);
		}
	}

	/**
	 * 
	 * 下载文件 文件流形式，返回拷贝字节数
	 * 
	 * @param remoteFile
	 *            远程文件路径(服务器端)
	 * @param localFile
	 *            本地文件路径(客户端)
	 * @throws Exception
	 * 
	 */
	public static int byteDownloadFtpFile(String remoteFile, String localFile) throws Exception {
		long count = 0;
		int n = 0;
		SocketInputStream is = null;
		FileOutputStream os = null;
		try {
			// 获取远程机器上的文件filename，借助TelnetInputStream把该文件传送到本地。
			is = (SocketInputStream) ftpClient.retrieveFileStream(remoteFile);
			File outfile = new File(localFile);
			if (!outfile.isDirectory()) {
				File tempfile = new File(StringFileUtils.getFilePath(localFile));
				if (!tempfile.exists()) {
					tempfile.mkdir();
				}
			}
			os = new FileOutputStream(outfile);

			byte[] bytes = new byte[1024];
			while ((n = is.read(bytes)) != -1) {
				os.write(bytes, 0, n);
				count += n;
			}
			logger.info("download success: " + remoteFile + "=>" + localFile);
			System.out.println("download success");
			return (int) count;
		} catch (Exception ex) {
			System.out.println("not download");
			ex.printStackTrace();
			throw new RuntimeException(ex);
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (os != null) {
						os.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// public static void main(String[] args) {
	// FtpUtils ftp =new FtpUtils();
	// //ftp.uploadFile("ftpFile/data", "123.docx", "E://123.docx");
	// //ftp.downloadFile("ftpFile/data", "123.docx", "F://");
	// ftp.deleteFile("ftpFile/data", "123.docx");
	// System.out.println("ok");
	// }
//
//	public static void main(String[] args) {
//		ArrayList<String> dirctorys = new ArrayList<String>();
//		FtpUtils.initFtpClient("10.0.1.177", 21, "tianji", "000000");
////		FtpUtils.initFtpClient("10.0.4.159", 21, "eric", "qaz789");
//		String fpath = "/home/tianji/Documents/pj/readNc/bin_duanlin";
////		String createPath = "/test/app/flink/data";
//		String createPath = "/home/tianji/Documents/pj/readNc/bin_duanlin/out_nc";
//		String fileName = "MCAPPI_X1001_20120721134000.txt";
//		String originfilename = "/test/app/flink/data/sources/X1001/nc/MCAPPI_X1001_20120721134000.txt";
////		dirctorys = FtpUtils.GetFileFtp2(fpath);
////		for (String string : dirctorys) {
////			System.out.println(string);
////			//从文件全路径中截取文件名：保留文件名及后缀
////			System.out.println(StringFileUtils.getFileNameWithSuffix(string));
////		}
//
//		//createPath上传ftp目录  ，fileName上传的文件名 ，本地文件全路径+文件名 有 bug ！
//		FtpUtils.uploadFile(createPath,  fileName,  originfilename);
//	}
}
